home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcl / src-16f.lha / ldb / sparc-assem.s < prev    next >
Text File  |  1992-05-19  |  14KB  |  511 lines

  1.  
  2. #include <machine/asm_linkage.h>
  3. #include <machine/psl.h>
  4. #include <machine/trap.h>
  5.  
  6. #define LANGUAGE_ASSEMBLY
  7. #include "lispregs.h"
  8. #include "lisp.h"
  9. #include "globals.h"
  10.  
  11. #define load(sym, reg) \
  12.         sethi   %hi(NAME(sym)), reg;    ld      [reg+%lo(NAME(sym))], reg
  13. #define store(reg, sym) \
  14.         sethi %hi(NAME(sym)), L0; st reg, [L0+%lo(NAME(sym))]
  15.  
  16.  
  17. #define FRAMESIZE (SA(WINDOWSIZE+4))
  18.  
  19.         .seg    "text"
  20.         .global NAME(call_into_lisp)
  21. NAME(call_into_lisp):
  22.         save    %sp, -FRAMESIZE, %sp
  23.  
  24.     /* Flush all of C's register windows to the stack. */
  25.     ta    ST_FLUSH_WINDOWS
  26.  
  27.         /* Save the return address. */
  28.         st      %i7, [%fp-4]
  29.  
  30.         /* Clear the descriptor regs. */
  31.         mov     ZERO, A0
  32.         mov     ZERO, A1
  33.         mov     ZERO, A2
  34.         mov     ZERO, A3
  35.         mov     ZERO, A4
  36.         mov     ZERO, A5
  37.         mov     ZERO, OCFP
  38.         mov     ZERO, LRA
  39.         mov     ZERO, L2
  40.         mov     ZERO, CODE
  41.  
  42.         /* Establish NIL */
  43.         set     NIL, NULLREG
  44.  
  45.         /* No longer in foreign function call. */
  46.         /* Note: the atomic flag should still be set. */
  47.         sethi   %hi(NAME(foreign_function_call_active)), NL0
  48.         st      ZERO, [NL0+%lo(NAME(foreign_function_call_active))]
  49.  
  50.         /* Load the rest of lisp state. */
  51.         load(current_dynamic_space_free_pointer, ALLOC)
  52.         load(current_binding_stack_pointer, BSP)
  53.         load(current_control_stack_pointer, CSP)
  54.         load(current_control_frame_pointer, OCFP)
  55.  
  56.         /* No longer atomic. */
  57.         sethi   %hi(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET), NL0
  58.         st      ZERO, [NL0+%lo(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET)]
  59.  
  60.         /* Were we interrupted? */
  61.         sethi   %hi(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET), NL0
  62.         ld      [NL0+%lo(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET)], NL0
  63.         tst     NL0
  64.         beq     1f
  65.         nop
  66.  
  67.         /* Yep, we were. */
  68.         unimp   trap_PendingInterrupt
  69. 1:
  70.  
  71.         /* Pass in the args. */
  72.         /* Note: CNAME and LEXENV already hold the correct values. */
  73.         mov     %i2, CFP
  74.         sll     %i3, 2, NARGS
  75.         ld      [CFP+0], A0
  76.         ld      [CFP+4], A1
  77.         ld      [CFP+8], A2
  78.         ld      [CFP+12], A3
  79.         ld      [CFP+16], A4
  80.         ld      [CFP+20], A5
  81.  
  82.         /* Calculate LRA */
  83.         set     lra + type_OtherPointer, LRA
  84.  
  85.         /* Indirect closure */
  86.         ld      [LEXENV+CLOSURE_FUNCTION_OFFSET], CODE
  87.  
  88.         jmp     CODE+FUNCTION_HEADER_CODE_OFFSET
  89.         nop
  90.  
  91.         .align  8
  92. lra:
  93.         .word   type_ReturnPcHeader
  94.  
  95.         /* Blow off any extra values. */
  96.         mov     OCFP, CSP
  97.         nop
  98.  
  99.         /* Return the one value. */
  100.         mov     A0, %i0
  101.  
  102.         /* Turn on pseudo_atomic */
  103.         set     1, NL1
  104.         sethi   %hi(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET), L0
  105.         st      NL1, [L0+%lo(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET)]
  106.  
  107.         /* Store LISP state */
  108.         store(ALLOC,current_dynamic_space_free_pointer)
  109.         store(BSP,current_binding_stack_pointer)
  110.         store(CSP,current_control_stack_pointer)
  111.         store(CFP,current_control_frame_pointer)
  112.  
  113.         /* No longer in Lisp. */
  114.         store(NL1,foreign_function_call_active)
  115.  
  116.         /* Were we interrupted? */
  117.         sethi   %hi(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET), L0
  118.         ld      [L0+%lo(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET)], L0
  119.         tst     L0
  120.         beq     1f
  121.         nop
  122.  
  123.         /* Yep, we were. */
  124.         unimp   trap_PendingInterrupt
  125. 1:
  126.  
  127.         /* Back to C we go. */
  128.     ld    [%sp+FRAMESIZE-4], %i7
  129.         ret
  130.         restore    %sp, FRAMESIZE, %sp
  131.  
  132.  
  133.  
  134.         .global _call_into_c
  135. _call_into_c:
  136.         /* Build a lisp stack frame */
  137.         mov     CFP, OCFP
  138.         mov     CSP, CFP
  139.         add     CSP, 32, CSP
  140.         st      OCFP, [CFP]
  141.         st      CODE, [CFP+8]
  142.  
  143.         /* Turn on pseudo-atomic. */
  144.         sethi   %hi(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET), L0
  145.         st      CSP, [L0+%lo(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET)]
  146.  
  147.     /* Convert the return address to an offset and save it on the stack. */
  148.     sub    LIP, CODE, L0
  149.     add    L0, type_OtherPointer, L0
  150.     st    L0, [CFP+4]
  151.  
  152.         /* Store LISP state */
  153.         store(ALLOC,current_dynamic_space_free_pointer)
  154.         store(BSP,current_binding_stack_pointer)
  155.         store(CSP,current_control_stack_pointer)
  156.         store(CFP,current_control_frame_pointer)
  157.  
  158.         /* No longer in Lisp. */
  159.         store(CSP,foreign_function_call_active)
  160.  
  161.         /* Were we interrupted? */
  162.         sethi   %hi(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET), L0
  163.         ld      [L0+%lo(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET)], L0
  164.         tst     L0
  165.         beq     1f
  166.         nop
  167.  
  168.         /* Yep, we were. */
  169.         unimp   trap_PendingInterrupt
  170. 1:
  171.  
  172.         /* Into C we go. */
  173.         call    CFUNC
  174.         nop
  175.  
  176.         /* Re-establish NIL */
  177.         set     NIL, NULLREG
  178.  
  179.         /* No longer in foreign function call. */
  180.         /* Note: the atomic flag should still be set. */
  181.         sethi   %hi(NAME(foreign_function_call_active)), NL1
  182.         st      ZERO, [NL1+%lo(NAME(foreign_function_call_active))]
  183.  
  184.         /* Load the rest of lisp state. */
  185.         load(current_dynamic_space_free_pointer, ALLOC)
  186.         load(current_binding_stack_pointer, BSP)
  187.         load(current_control_stack_pointer, CSP)
  188.         load(current_control_frame_pointer, CFP)
  189.  
  190.     /* Get the return address back. */
  191.     ld    [CFP+4], LIP
  192.     ld    [CFP+8], CODE
  193.     add    LIP, CODE, LIP
  194.     sub    LIP, type_OtherPointer, LIP
  195.  
  196.         /* No longer atomic. */
  197.         sethi   %hi(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET), NL1
  198.         st      ZERO, [NL1+%lo(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET)]
  199.  
  200.         /* Were we interrupted? */
  201.         sethi   %hi(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET), NL1
  202.         ld      [NL1+%lo(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET)], NL1
  203.         tst     NL1
  204.         beq     1f
  205.         nop
  206.  
  207.         /* Yep, we were. */
  208.         unimp   trap_PendingInterrupt
  209. 1:
  210.  
  211.         /* Reset the lisp stack. */
  212.         /* Note: OCFP is in one of the locals, it gets preserved across C. */
  213.         mov     CFP, CSP
  214.         mov     OCFP, CFP
  215.  
  216.         /* And back into lisp. */
  217.         ret
  218.         nop
  219.  
  220.  
  221.  
  222.  
  223.         .global _undefined_tramp
  224.         .align  8
  225.         .byte   0
  226. _undefined_tramp:
  227.         .byte   0, 0, type_FunctionHeader
  228.         .word   _undefined_tramp
  229.         .word   NIL
  230.         .word   NIL
  231.         .word   NIL
  232.         .word   NIL
  233.  
  234.     b    1f
  235.         unimp   trap_Cerror
  236.     .byte    4, 23, 254, 12, 3
  237.     .align    4
  238. 1:
  239.     ld    [CNAME+SYMBOL_RAW_FUNCTION_ADDR_OFFSET], CODE
  240.     jmp    CODE+FUNCTION_HEADER_CODE_OFFSET
  241.     nop
  242.  
  243.     .global    _closure_tramp
  244.     .align    8
  245.     .byte    0
  246. _closure_tramp:
  247.     .byte    0, 0, type_FunctionHeader
  248.     .word    _closure_tramp
  249.     .word    NIL
  250.         .word   NIL
  251.     .word    NIL
  252.     .word    NIL
  253.  
  254.     ld    [CNAME+SYMBOL_FUNCTION_OFFSET], LEXENV
  255.     ld    [LEXENV+CLOSURE_FUNCTION_OFFSET], CODE
  256.     jmp    CODE+FUNCTION_HEADER_CODE_OFFSET
  257.     nop
  258.  
  259.  
  260.  
  261. /*
  262.  * Function-end breakpoint magic.
  263.  */
  264.  
  265.     .text
  266.     .align    8
  267.     .global    _function_end_breakpoint_guts
  268. _function_end_breakpoint_guts:
  269.     .word    type_ReturnPcHeader
  270.     b    1f
  271.     nop
  272.     mov    CSP, OCFP
  273.     add    4, CSP, CSP
  274.     mov    4, NARGS
  275.     mov    NULLREG, A1
  276.     mov    NULLREG, A2
  277.     mov    NULLREG, A3
  278.     mov    NULLREG, A4
  279.     mov    NULLREG, A5
  280. 1:
  281.  
  282.     .global    _function_end_breakpoint_trap
  283. _function_end_breakpoint_trap:
  284.     unimp    trap_FunctionEndBreakpoint
  285.     b    1b
  286.     nop
  287.  
  288.     .global    _function_end_breakpoint_end
  289. _function_end_breakpoint_end:
  290.  
  291.  
  292.  
  293.  
  294. /****************************************************************\
  295.  
  296. We need our own version of sigtramp.
  297.  
  298. \****************************************************************/
  299.  
  300.     .global    __sigtramp, __sigfunc
  301. __sigtramp:
  302.     !
  303.     ! On entry sp points to:
  304.     !     0 - 63: window save area
  305.     !    64: signal number
  306.     !    68: signal code
  307.     !    72: pointer to sigcontext
  308.     !    76: addr parameter
  309.     !
  310.     ! A sigcontext looks like:
  311.     !    00: on signal stack flag
  312.     !    04: old signal mask
  313.     !    08: old sp
  314.     !    12: old pc
  315.     !    16: old npc
  316.     !    20: old psr
  317.     !    24: old g1
  318.     !    28: old o0
  319.     !
  320.         ! Out sigcontext has the following added:
  321.         !       32: regs[32]
  322.         !       160: fpregs[32]
  323.         !       288: y
  324.         !       292: fsr
  325.         !
  326.         ! After we allocate space for the new sigcontext, the stack looks like:
  327.         !       < window save area, etc >
  328.         !       SCOFF: start of generic sigcontext.
  329.         !       IREGSOFF: start of lisp sigcontext.
  330.         !       SIGNUM: signal number
  331.         !       CODE: signal code
  332.         !       OSCP: pointer to orig sigcontext
  333.         !       ADDR: addr parameter (which isn't supplied by the kernel)
  334.  
  335. #define SCOFF SA(MINFRAME)
  336. #define IREGSOFF SCOFF+32
  337. #define FPREGSOFF IREGSOFF+(32*4)
  338. #define YOFF FPREGSOFF+(32*4)
  339. #define FSROFF YOFF+4
  340. #define SCSIZE SA(32+(32*4)+(32*4)+4+4)
  341. #define SIGNUMOFF SCOFF+SCSIZE
  342. #define CODEOFF SCOFF+SCSIZE+4
  343. #define ADDROFF SCOFF+SCSIZE+12
  344.  
  345. #ifdef MACH
  346. #define OSCOFF ADDROFF
  347. #else
  348. #define OSCOFF SCOFF+SCSIZE+16
  349. #endif
  350.  
  351.         ! Allocate space for our sigcontext.
  352.         sub     %sp, SCSIZE+SA(MINFRAME)-64, %sp
  353.  
  354.         ! Save integer registers.
  355.         ! Note: the globals and outs are good, but the locals and ins have
  356.         ! been trashed.  But luckly, they have been saved on the stack.
  357.         ! So we need to extract the saved stack pointer from the sigcontext
  358.         ! to determine where they are.
  359.         std     %g0, [%sp+IREGSOFF]
  360.         std     %g2, [%sp+IREGSOFF+8]
  361.         std     %g4, [%sp+IREGSOFF+16]
  362.         std     %g6, [%sp+IREGSOFF+24]
  363.         std     %o0, [%sp+IREGSOFF+32]
  364.         ld      [%sp + OSCOFF+8], %o0
  365.         std     %o2, [%sp+IREGSOFF+40]
  366.         std     %o4, [%sp+IREGSOFF+48]
  367.         st      %o0, [%sp+IREGSOFF+56]
  368.         st      %o7, [%sp+IREGSOFF+60]
  369.  
  370.         ldd     [%o0], %l0
  371.         ldd     [%o0+8], %l2
  372.         ldd     [%o0+16], %l4
  373.         ldd     [%o0+24], %l6
  374.         ldd     [%o0+32], %i0
  375.         ldd     [%o0+40], %i2
  376.         ldd     [%o0+48], %i4
  377.         ldd     [%o0+56], %i6
  378.         std     %l0, [%sp+IREGSOFF+64]
  379.         std     %l2, [%sp+IREGSOFF+72]
  380.         std     %l4, [%sp+IREGSOFF+80]
  381.         std     %l6, [%sp+IREGSOFF+88]
  382.         std     %i0, [%sp+IREGSOFF+96]
  383.         std     %i2, [%sp+IREGSOFF+104]
  384.         std     %i4, [%sp+IREGSOFF+112]
  385.         std     %i6, [%sp+IREGSOFF+120]
  386.  
  387.         ! Copy the original sigcontext down to our sigcontext.
  388.         ld      [%sp + OSCOFF], %l0
  389.         ld      [%sp + OSCOFF+4], %l1
  390.         ld      [%sp + OSCOFF+8], %l2
  391.         ld      [%sp + OSCOFF+12], %l3
  392.         ld      [%sp + OSCOFF+16], %l4
  393.         ld      [%sp + OSCOFF+20], %l5
  394.         ld      [%sp + OSCOFF+24], %l6
  395.         ld      [%sp + OSCOFF+28], %l7
  396.         std     %l0, [%sp+SCOFF]
  397.         std     %l2, [%sp+SCOFF+8]
  398.         std     %l4, [%sp+SCOFF+16]
  399.         std     %l6, [%sp+SCOFF+24]
  400.  
  401.         ! Check to see if we need to save the fp regs.
  402.     set    PSR_EF, %l0
  403.     mov    %y, %l2            ! save y
  404.     btst    %l0, %l5        ! is FPU enabled?
  405.     bz    1f            ! if not skip FPU save
  406.     st    %l2, [%sp + YOFF]
  407.  
  408.     std    %f0, [%sp + FPREGSOFF+(0*4)]    ! save all fpu registers.
  409.     std    %f2, [%sp + FPREGSOFF+(2*4)]
  410.     std    %f4, [%sp + FPREGSOFF+(4*4)]
  411.     std    %f6, [%sp + FPREGSOFF+(6*4)]
  412.     std    %f8, [%sp + FPREGSOFF+(8*4)]
  413.     std    %f10, [%sp + FPREGSOFF+(10*4)]
  414.     std    %f12, [%sp + FPREGSOFF+(12*4)]
  415.     std    %f14, [%sp + FPREGSOFF+(14*4)]
  416.     std    %f16, [%sp + FPREGSOFF+(16*4)]
  417.     std    %f18, [%sp + FPREGSOFF+(18*4)]
  418.     std    %f20, [%sp + FPREGSOFF+(20*4)]
  419.     std    %f22, [%sp + FPREGSOFF+(22*4)]
  420.     std    %f24, [%sp + FPREGSOFF+(24*4)]
  421.     std    %f26, [%sp + FPREGSOFF+(26*4)]
  422.     std    %f28, [%sp + FPREGSOFF+(28*4)]
  423.     std    %f30, [%sp + FPREGSOFF+(30*4)]
  424.     st    %fsr, [%sp + FSROFF] ! save old fsr
  425. 1:
  426.  
  427.     ld    [%sp + SIGNUMOFF], %o0    ! get signal number
  428.     set    __sigfunc, %g1        ! get array of function ptrs
  429.     sll    %o0, 2, %g2        ! scale signal number for index
  430.     ld    [%g1 + %g2], %g1    ! get func
  431.     ld    [%sp + CODEOFF], %o1    ! get code
  432.         add     %sp, SCOFF, %o2         ! compute scp
  433.     call    %g1            ! (*_sigfunc[sig])(sig,code,scp,addr)
  434.     ld    [%sp + ADDROFF], %o3    ! get addr
  435.  
  436.         ! Recompute scp, and call into _sigreturn
  437.         add     %sp, SCOFF, %o0
  438.  
  439.  
  440.         .global _sigreturn
  441. _sigreturn:
  442.         ! Move values we can't restore directory into real sigcontext.
  443.         ld      [%o0+32+(4*1)], %l0     ! g1
  444.         ld      [%o0+32+(4*8)], %l1     ! o0
  445.         ld      [%o0+32+(4*14)], %l2    ! sp
  446.         st      %l0, [%o0+24]
  447.         st      %l1, [%o0+28]
  448.         st      %l2, [%o0+8]
  449.  
  450.     ld    [%o0 + 20], %l2        ! get psr
  451.     set    PSR_EF, %l0
  452.     ld    [%o0 + 288], %l1        ! restore y
  453.     btst    %l0, %l2        ! is FPU enabled?
  454.     bz    2f            ! if not skip FPU restore
  455.     mov    %l1, %y
  456.  
  457.     ldd    [%o0 + 160+(0*4)], %f0    ! restore all fpu registers.
  458.     ldd    [%o0 + 160+(2*4)], %f2
  459.     ldd    [%o0 + 160+(4*4)], %f4
  460.     ldd    [%o0 + 160+(6*4)], %f6
  461.     ldd    [%o0 + 160+(8*4)], %f8
  462.     ldd    [%o0 + 160+(10*4)], %f10
  463.     ldd    [%o0 + 160+(12*4)], %f12
  464.     ldd    [%o0 + 160+(14*4)], %f14
  465.     ldd    [%o0 + 160+(16*4)], %f16
  466.     ldd    [%o0 + 160+(18*4)], %f18
  467.     ldd    [%o0 + 160+(20*4)], %f20
  468.     ldd    [%o0 + 160+(22*4)], %f22
  469.     ldd    [%o0 + 160+(24*4)], %f24
  470.     ldd    [%o0 + 160+(26*4)], %f26
  471.     ldd    [%o0 + 160+(28*4)], %f28
  472.     ldd    [%o0 + 160+(30*4)], %f30
  473.     ld    [%o0 + 160+(33*4)], %fsr    ! restore old fsr
  474. 2:
  475.  
  476.     ! The locals and in are restored from the stack, so we have to put
  477.     ! them there.
  478.     ld    [%o0 + 8], %o1
  479.         ldd     [%o0 + 32+(16*4)], %l0
  480.         ldd     [%o0 + 32+(18*4)], %l2
  481.         ldd     [%o0 + 32+(20*4)], %l4
  482.         ldd     [%o0 + 32+(22*4)], %l6
  483.         ldd     [%o0 + 32+(24*4)], %i0
  484.         ldd     [%o0 + 32+(26*4)], %i2
  485.         ldd     [%o0 + 32+(28*4)], %i4
  486.         ldd     [%o0 + 32+(30*4)], %i6
  487.     std    %l0, [%o1 + (0*4)]
  488.     std    %l2, [%o1 + (2*4)]
  489.     std    %l4, [%o1 + (4*4)]
  490.     std    %l6, [%o1 + (6*4)]
  491.     std    %i0, [%o1 + (8*4)]
  492.     std    %i2, [%o1 + (10*4)]
  493.     std    %i4, [%o1 + (12*4)]
  494.     std    %i6, [%o1 + (14*4)]
  495.  
  496.         ! Restore the globals and outs.  Don't restore %g1, %o0, or %sp
  497.     ! 'cause they get restored from the sigcontext.
  498.         ldd     [%o0 + 32+(2*4)], %g2
  499.         ldd     [%o0 + 32+(4*4)], %g4
  500.         ldd     [%o0 + 32+(6*4)], %g6
  501.         ld      [%o0 + 32+(9*4)], %o1
  502.         ldd     [%o0 + 32+(10*4)], %o2
  503.         ldd     [%o0 + 32+(12*4)], %o4
  504.         ld      [%o0 + 32+(15*4)], %o7
  505.  
  506.     set    139, %g1        ! sigcleanup system call
  507.     t    0
  508.     unimp    0            ! just in case it returns
  509.     /*NOTREACHED*/
  510.  
  511.